<?php

class ClassStructure_Weaved_Layers extends ClassStructure_Weaved_Delegator {
    
    /**
     * Class constructer: encapsulates the supplied object and prepares this class
     * with information about the available method signatures.
     *
     * @access public
     * @param object $obj The object to encapsulate and become a base layer.
     * @return object
     */
    public function __construct($obj) {
        
        parent::__construct($obj);
        
    }
    
    /**
     * Iterates through the supplied object's methods to chain before or after the
     * base method.
     *
     * The parameter signature of each method must match that of the base layer 
     * method - or have no parameters at all.
     *
     * This method uses PHP's Reflection classes.
     *
     * @final final 
     * @access protected
     * @param object $obj The object to iterate through its methods.
     * @param string $enm_order Whether to put the method invocation before or
     *      after the base method. Defaults to 'after'.
     * @param array $arr_options An array of layer options.
     * @return void
     */
    final protected function __weaveObject($obj, $enm_type, $arr_options = array()) {
        
        if(!is_object($obj)) {
            return;
        }
        
        // retrieve the supplied object's available methods
        $arr_methods = $this->getAvailableMethods($obj);
        
        // iterate through each method and try to add it as a layer
        foreach($arr_methods as $str_method => $obj_method) {
            
            $clb_callable = array($obj, $str_method);
            
            if($this->__hasMethod($str_method)) {
                $this->__weaveAdvice($clb_callable, $str_method, $enm_type, $arr_options);
            }
            
        }
        
    }
    
    public function __weaveObjectBefore($obj, $arr_options = array()) {
        $this->__weaveObject($obj, self::WEAVE_ADVICE_BEFORE_BASE, $arr_options);
    }
    
    public function __weaveObjectAfter($obj, $arr_options = array()) {
        $this->__weaveObject($obj, self::WEAVE_ADVICE_AFTER_BASE, $arr_options);
    }
    
}

?>
